Add SAP Business Partner example for the ontology layer - #310
Add SAP Business Partner example for the ontology layer#310marioapiphani wants to merge 1 commit into
Conversation
An ontology-layer model of a Business Partner domain, exercising entity subtyping with a derived population, four-part compound identity, value types with requires constraints, associations with and without functional multiplicity, verbalizations, and ontology_mappings to a logical model. Validates against ontology/ontology.json as shipped.
|
Could you provide the original data model? |
|
Also curious, if there are some properties missing in Ossie? |
| a closed-world assumption. | ||
| extends: [ BusinessPartner ] | ||
| derived_by: | ||
| - "EXISTS ( BusinessPartner.customer_nr )" |
There was a problem hiding this comment.
derived_by requires EXISTS ( BusinessPartner.customer_nr) , but customer_nr has no link_mapping anywhere in the BusinessPartner nor CUSTOMER_SALES_AREA has a field that could feed it.
Running this file's own mapping yields zero Customer objects, so the derived-population feature this example is meant to demonstrate can't actually be observed.
| derived_by: | ||
| - "EXISTS ( BusinessPartner.customer_nr )" | ||
| relationships: | ||
| - name: has_sales_area |
There was a problem hiding this comment.
There's no concept: Customer entry anywhere in concept_mappings, only BusinessPartner and CustomerSalesArea are mapped.
has_sales_area gets zero link_mappings and zero derived_by, so this relationship (meant to illustrate "association without functional multiplicity") can never by populated.
| relationships: | ||
| - name: customer | ||
| roles: | ||
| - concept: Customer |
There was a problem hiding this comment.
These look like the same real-world relationship modeled as two independent declarations instead of one dual-verbalized relationship, the pattern ontology.md's Person.parent_of uses.
That means keeping them in sync by hand, and as noted above, the Customer.has_sales_area side isn't even mapped.
| multiplicity: ManyToOne | ||
| verbalizes: | ||
| - "{CustomerSalesArea} covers division {Division}" | ||
| - name: delivery_blocked |
There was a problem hiding this comment.
DELIVERY_BLOCK exists in the CUSTOMER_SALES_AREA dataset specifically for this, but CustomerSalesArea's concept_mapping stops after division, there's no delivery_blocked link_mapping. Compare flights.yaml's canceled flag, mapped via FLIGHT.id WHERE ( FLIGHT.cancelled == TRUE ), for the pattern this is missing.
| - relationship: nr | ||
| expression: "BUSINESS_PARTNER.BP_NUMBER" | ||
| children: | ||
| - relationship: BusinessPartner.category |
There was a problem hiding this comment.
These LinkMapping.relationship values are concept-qualified, but ontology.md's worked example and every occurence in flights.yaml use bare relationship names for LinkMapping.relationship (concept-qualification is for ReferentMapping.relationship instead).
If the mapping engine resolves by exact local name, category/full_name/country would never resolve and stay unpopulated.
| population from a country dataset rather than enumerating values here. | ||
| extends: [ String ] | ||
| requires: | ||
| - "LENGTH(CountryCode) = 2" |
There was a problem hiding this comment.
This is the only bare = in the file/corpus, every sibling constraint uses <= and ontology.md/flights.yaml use == exclusivity for equality. Worth double-checking the ontology-layer expression dialect accepts bare =. Separately, SAP's LAND1 field is commonly CHAR(3), so an exact length-2 constraint would reject legitimate 3-character country codes.
| - referent_mappings: | ||
| - relationship: customer | ||
| referent_mappings: | ||
| - relationship: BusinessPartner.nr |
There was a problem hiding this comment.
Customer declares no identify_by of its own, and neither the spec nor the schema says whether identify_by is inherited via extends ("inherit" doesn't appear anywhere in ontology.md/spec.md/the JSON schemas).
Worth flagging that against the actual converter, identify_by is built only from a concept's own YAML list, so Customer.identify_by resolved {} here.
On top of that, lookup_concept_relationship always prefixes f"{concept.name}.{name}", so an already-qualified value like BusinessPartner.nr would get double-prefixed and fail to resolve. This isn't specific to this file (it'd hit ontology.md's own CustOrder.nr example too), but this PR looks like the first example to actually exercise this path.
| - concept: CountryCode | ||
| type: ValueType | ||
| description: > | ||
| Country key. Technical origin: DDIC domain LAND1, check table T005. |
There was a problem hiding this comment.
This says population comes "from a country dataset" preserving the T005 check-table relationship, but no such dataset exists in ontology_mappings (the actual mapping just copies BUSINESS_PARTNER.COUNTRY straight through.
It might be worth correcting the description or adding the dataset it describes.
|
|
||
| # ---- Value types carrying DDIC domain semantics ------------------------- | ||
|
|
||
| - concept: BusinessPartnerNumber |
There was a problem hiding this comment.
The six sibling ValueType.requires blocks mix block-list and inline-flow YAML style for structurally identical constraints. Given this file is meant as a template for future SAP fields, a consistent style would help (and might have caught the = 2 issue 😄 ).
examples/has one ontology-layer example today (flights.yaml). This adds a second, drawn from an enterprise ERP domain, that exercises ontology constructs the existing example does not reach:Customerdeclaresextends: [ BusinessPartner ];flights.yamlhas no EntityType subtypingCustomeruses concept-levelderived_byto define its population as exactly those business partners carrying a customer number, rather than asserting it.flights.yamlusesderived_byonly on relationships, for derived attributes.CustomerSalesAreais identified by customer + sales organization + distribution channel + division. The existing example tops out at two parts.It also covers ground shared with
flights.yaml— value types withrequires, associations with and without functional multiplicity, verbalizations in both reading directions, andontology_mappingsdown to a logical model — so it stands alone as a reading example.Source-system provenance (SAP Data Dictionary domains and check tables) is recorded in the descriptions, showing one way to keep technical origin alongside a business-level model.
The README's
examples/entry is updated to name both ontology-layer models.The file validates against
ontology/ontology.jsonas shipped, withcore-spec/osi-schema.jsonregistered to resolve the remote$reffrom the checkout:Prints
VALID. No code changes.🤖 Generated with Claude Code